//
//  SHKVOViewController.m
//  SDemo
//
//  Created by gg on 2018/8/1.
//  Copyright © 2018年 gg. All rights reserved.
//

#import "SHKVOViewController.h"
#import "SHCar.h"
#import <objc/message.h>
@interface SHKVOViewController ()

@end

@implementation SHKVOViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"KVO 的底层实现";
    self.view.backgroundColor = [UIColor greenColor];
    
    [self kvoimplementation];
}

//kvo 底层探索
-(void) kvoimplementation {
    SHCar *car1 = [[SHCar alloc] init];
    SHCar *car2 = [[SHCar alloc] init];
    
    id carclass1 =  object_getClass(car1);
    id carclass2 =  object_getClass(car2);
    
    
    NSLog(@"kvo 监听前：car1 %@  car2 %@",object_getClass(car1),object_getClass(car2));
    
    [car1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
    
    carclass1 =  object_getClass(car1);
    carclass2 =  object_getClass(car2);
    
    id super_carclass1 =  class_getSuperclass(carclass1);
    id super_carclass2 =   class_getSuperclass(carclass2);
    
    /**
     输出结果直观看出
     
     2018-08-01 14:12:00.338448+0800 SDemo[71170:2005659] kvo 监听前：car1 SHCar  car2 SHCar
     2018-08-01 14:12:00.338932+0800 SDemo[71170:2005659] kvo 监听后：car1 NSKVONotifying_SHCar  car2 SHCar
     
     */
    NSLog(@"kvo 监听后：car1 %@  car2 %@",object_getClass(car1),object_getClass(car2));
    
    /**
     输出结果
     
     2018-08-01 14:44:53.522126+0800 SDemo[71733:2035305] kvo 监听后：car1父类 SHCar  car2父类 NSObject
     
     */
    NSLog(@"kvo 监听后：car1父类 %@  car2父类 %@",super_carclass1,super_carclass2);
    
    
    /**
     输出内部的方法列表和属性列表
     
     2018-08-01 14:44:53.522528+0800 SDemo[71733:2035305] method1 [/nsetName:
     class
     dealloc
     _isKVOA
     [
     2018-08-01 14:44:53.522786+0800 SDemo[71733:2035305] method2 [/n.cxx_destruct
     name
     setName:
     [
     
     */
    NSString *method1 = [self getMethodAndPropote:carclass1];
    NSString *method2 = [self getMethodAndPropote:carclass2];
    NSLog(@"method1 %@",method1);
    NSLog(@"method2 %@",method2);
    
    car1.name = @"car1";
    car2.name = @"car2";
}


-(NSString *)getMethodAndPropote:(id)obj {
    
    unsigned int count = 0;
    Method *methondArr = class_copyMethodList([obj class], &count);
    NSMutableString *methodStr = [NSMutableString string];
    [methodStr appendString:@"[/n"];
    for (int i = 0; i < count; i ++) {
        Method method = methondArr[i];
        SEL sel = method_getName(method);
        [methodStr appendFormat:@"%@",NSStringFromSelector(sel)];
        [methodStr appendString:@"\n"];
    }
    
    [methodStr appendString:@"["];
    free(methondArr);
    
    return methodStr;
}


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    NSLog(@"结果：%@",change);
}


-(void) iniData {
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}



@end
